package w.z.x.framework.repository.interfaces;

import java.beans.Introspector;
import java.io.Serializable;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.function.Function;

/**
 * 支持序列化的 Function
 *
 * @author 魏祖潇
 */
@FunctionalInterface
public interface SerialFunction<T, R> extends Function<T, R>, Serializable {

    /**
     * 获取字段
     *
     * @param func lambda引用
     * @param <T>  泛型
     * @return 字段
     */
    static <T> Field field(SerialFunction<T, ?> func) {
        try {
            Method method = func.getClass().getDeclaredMethod("writeReplace");
            method.setAccessible(Boolean.TRUE);
            SerializedLambda lambda = (SerializedLambda) method.invoke(func);
            Class clazz = Class.forName(lambda.getImplClass().replace("/", "."));
            String getter = lambda.getImplMethodName();
            String fieldName = Introspector.decapitalize(getter.replace("get", ""));
            return clazz.getDeclaredField(fieldName);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
